package be.roam.drest.service.twitter;

import java.io.IOException;
import java.io.InputStream;
import java.util.Set;

import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.lang.StringEscapeUtils;
import org.xml.sax.SAXException;

import be.roam.drest.service.common.HttpRestService;
import be.roam.drest.service.twitter.xml.TwitterXmlParser;
import be.roam.util.StringUtil;

public class TwitterService extends HttpRestService {

	private static final String TWITTER_URL = "http://twitter.com/statuses/";

	/**
     * The Twitter authentication scope.
     */
    private static final AuthScope TWITTER_AUTH_SCOPE = new AuthScope("twitter.com", 80, "Twitter API");

    /**
     * User name (email address).
     */
    private String login;

    /**
     * Password.
     */
    private String password;

    /**
     * The credentials (created from user name and password).
     */
    private Credentials credentials;

    /**
     * Constructor.
     */
    public TwitterService() {
        super();
    }

    /**
     * Constructor.
     *
     * @param login the screen name (or email address)
     * @param password the password for the user
     */
    public TwitterService(String login, String password) {
        super();
        setCredentials(login, password);
    }

    /**
     * Sets the credentials for the service.
     *
     * @param userName the user name (email address)
     * @param password the password for the user
     */
    public void setCredentials(String userName, String password) {
        this.login = userName;
        this.password = password;
        credentials = new UsernamePasswordCredentials(userName, password);
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
        if (!StringUtil.isNullOrEmpty(password)) {
            credentials = new UsernamePasswordCredentials(login, password);
        }
    }

    /**
     * @return the screen name or email address
     */
    public String getLogin() {
        return login;
    }

    /**
     * @param login the screen name or email address
     */
    public void setLogin(String login) {
        this.login = login;
        if (!StringUtil.isNullOrEmpty(login)) {
            credentials = new UsernamePasswordCredentials(login, password);
        }
    }

    public InputStream getPublicTimelineRaw() throws IOException {
    	client.getState().setCredentials(TWITTER_AUTH_SCOPE, credentials);
    	GetMethod method = createGetMethod(TWITTER_URL + "public_timeline.xml");
    	method.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
        client.executeMethod(method);
        // TODO Handle response codes
        return method.getResponseBodyAsStream();
    }

    public Set<TwitterStatus> getPublicTimeline() throws IOException, SAXException {
    	InputStream inputStream = getPublicTimelineRaw();
    	return getTimeline(inputStream);
    }

    public InputStream getSelfAndFriendsTimelineRaw() throws IOException {
    	client.getState().setCredentials(TWITTER_AUTH_SCOPE, credentials);
    	GetMethod method = createGetMethod(TWITTER_URL + "friends_timeline.xml");
    	method.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
        client.executeMethod(method);
        // TODO Handle response codes
        return method.getResponseBodyAsStream();
    }

    public Set<TwitterStatus> getSelfAndFriendsTimeline() throws IOException, SAXException {
    	InputStream inputStream = getSelfAndFriendsTimelineRaw();
    	return getTimeline(inputStream);
    }

	private Set<TwitterStatus> getTimeline(InputStream inputStream) throws SAXException, IOException {
		if (inputStream == null) {
    		return null;
    	}
    	Set<TwitterStatus> set = TwitterXmlParser.parseStatus(inputStream);
    	inputStream.close();
    	return set;
	}

    public void update(String text) throws IOException {
    	client.getState().setCredentials(TWITTER_AUTH_SCOPE, credentials);
    	PostMethod method = createPostMethod(TWITTER_URL + "update.xml");
    	method.setParameter("status", StringEscapeUtils.escapeHtml(text));
    	method.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
    	// TODO Handle response codes
    	client.executeMethod(method);
    }

}
